/*
 * Copyright 2011 Helios Technologies.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.heliostech.gwt.widget.dialog.error;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.resources.client.ClientBundle;
import com.google.gwt.resources.client.CssResource;
import com.google.gwt.resources.client.CssResource.ImportedWithPrefix;
import com.google.gwt.resources.client.ImageResource;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.DisclosurePanel;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.IsWidget;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.heliostech.gwt.widget.dialog.base.BaseDialog;

/**
 * @author ldesdier
 *
 */
public class ErrorDialog extends BaseDialog {

	public interface Resources extends ClientBundle {	
		@Source("./error.png")
		ImageResource errorIcon();		
		@Source(Style.DEFAULT_CSS)
		@CssResource.NotStrict
	    Style errorDialogStyle();
	}
	
	@ImportedWithPrefix("helios-ErrorDialog")
	public interface Style extends CssResource {
		String DEFAULT_CSS = "com/heliostech/gwt/widget/dialog/error/ErrorDialog.css";
		
		String errorDialogWidget();
		String headLabel();
		String error();
		String disclosure();
		String detailContainer();
		String closeButton();
	}
	
	private static Resources DEFAULT_RESOURCES;
	private static Resources getDefaultResources() {
		if (DEFAULT_RESOURCES == null) {
			DEFAULT_RESOURCES = GWT.create(Resources.class);
		}
		return DEFAULT_RESOURCES;
	}	
	private final Style style;
	
	private final Label error;
	private final FlowPanel solutionContainer;
	private final DisclosurePanel detail;
	private final ScrollPanel detailContainer;
	
	/**
	 * Create a new ErrorDialog using the default resources.
	 */
	public ErrorDialog() {
		this(getDefaultResources());
	}
	
	/**
	 * Create a new ErrorDialog using the specified resources.
	 * @param res The resources to be used.
	 */
	public ErrorDialog(Resources res) {
		super("Error", true, true);
		DEFAULT_RESOURCES = res;
		this.style = res.errorDialogStyle();
		this.style.ensureInjected();
		addStyleName(style.errorDialogWidget());
		setDialogDescription("An Error Occured", 
				"Click on the [Close] button to dismiss this message", res.errorIcon());
		setSize("30em","20em");
		
		// First show the error that occured
		final Label l1 = new Label("The application has encountered the following error:");
		l1.addStyleName(style.headLabel());
		error = new Label();
		error.addStyleName(style.error());
		
		// If set show the error solution.
		solutionContainer = new FlowPanel();
		solutionContainer.setVisible(false);
		
		detail = new DisclosurePanel("More information");
		detail.addStyleName(style.disclosure());
		detailContainer = new ScrollPanel();
		detailContainer.setHeight("6.5em");
		detailContainer.addStyleName(style.detailContainer());
		detail.add(detailContainer);
		detail.setVisible(false);
		
		final FlowPanel cc = new FlowPanel();
		cc.add(l1);
		cc.add(error);
		cc.add(solutionContainer);	
		cc.add(detail);
		setContent(cc);
		
		
		final Button closeB = new Button("Close");
		closeB.addStyleName(style.closeButton());
		closeB.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				hide();
			}
		});
		addButton(closeB);
	}
	
	/**
	 * Set the error to be displayed.
	 * @param err The error to be displayed as a String.
	 */
	public void setError(String err) {
		error.setText(err);
	}
	
	/**
	 * Set more information about the displayed error.
	 * @param details The details of the displayed error.
	 */
	public void setDetails(ErrorDetail d) {
		detailContainer.setWidget(d);
		detail.setVisible(true);
	}
	
	/**
	 * Set the solution to the displayed error.
	 * @param solution The solution to be displayed as a String.
	 */
	public void setSolution(String solution) {
		solutionContainer.add(new Label(solution));
		solutionContainer.setVisible(true);
	}
	
	/**
	 * Set the solution to the displayed error.
	 * @param sw The solution to be displayed as a Widget implementation.
	 */
	public void setSolution(IsWidget sw) {
		solutionContainer.add(sw);
		solutionContainer.setVisible(true);
	}

	/* (non-Javadoc)
	 * @see com.heliostech.gwt.widget.dialog.base.BaseDialog#cleanup()
	 */
	@Override
	public void cleanup() {
		super.cleanup();
		error.setText("");
		solutionContainer.clear();
		solutionContainer.setVisible(false);
		detailContainer.clear();
		detail.setVisible(false);
	}
	
}
